<?php if (!defined('RH_module')) die();

global $config;
$config = array(
	'dir.install'    => $_base_dir,
	'dir.localstate' => $_base_dir.'var/',
	'dir.cache'      => $_base_dir.'var/cache/',
	'dir.store'      => $_base_dir.'var/store/',
	'dir.config'     => $_base_dir.'etc/',
	'dir.conf.d'     => $_base_dir.'etc/conf.d/',

	'digest_store'   => $_base_dir.'var/cache/digest_store.php',

	'form_auth' => array(
		'type' => 'form',
		'title' => 'Добро пожаловать',
		'fields' => array(
					'login' => array(
						'type' => 'text',
						'title' => 'Электронная почта',
						'description' => '',
					),
					'password' => array(
						'type' => 'password',
						'title' => 'Пароль',
						'description' => '',
					),
		),
		'validator' => 'install_validate_auth',
		'config_file' => $_base_dir.'etc/config.php',
		'buttons' => array(
			'ok' => array(
				'type' => 'image',
				'title' => 'Установить',
				'src' => '../skins/platonica/images/title/button-enter.png',
			),
		),
	),

);


function install_session_start ()
{
	static $session_started;
	if (!isset($session_started)) return $session_started = session_start();
	return $session_started;
} // end of function install_session_start

function install_authenticate($b=NULL)
{
	install_session_start();
	if (isset($b)) {
		$_SESSION['install']['authenticated'] = $b;
	}
	return isset($_SESSION['install']['authenticated']) && $_SESSION['install']['authenticated'];
}

function install_logout()
{
	install_session_start();
	unset($_SESSION['install']['authenticated']);
	return true;
}

function handle ()
{
	global $config;
	header("Content-type: text/html; charset=UTF-8");

	$_base_dir = $config['dir.install'];

	request_init();
	$action = request_get_param('m', install_authenticate() ? 'about' : 'auth');

	$safe_actions = array('auth', 'email');
	if (!install_authenticate() && !in_array($action, $safe_actions)) {
		request_redirect('?m=auth');
	}

	$f = 'handle_'.$action;
	$h = $f.'_'.$_SERVER['REQUEST_METHOD'];

	$module = 'admin/modules/'.$action.'/index.php';

	ob_start();
		require_once $_base_dir.$module;
			if     (is_callable($h)) $env = $h();
			elseif (is_callable($f)) $env = $f();
		$body =
	ob_get_clean();

	if ($env !== false && $env !== 1) {
		$env = array();
		if ($body) { $env['body'] = $body; $env['_t']['body'] = 'html'; }
	}
	return $env;

} // end of function main

function handle_ok ()
{
	//install_authenticate(false);
	disp_installation_success();
} // end of function handle_ok
function handle_failed ()
{
	disp_installation_failed();
} // end of function handle_ok
function handle_email ()
{
	global $config;

	// предварительные тесты прошли успешно, рисуем форму для ввода данных
	$key = request_get_param('d', NULL);
	if (!isset($key)) {
		return disp_email_verification_failed();
	}
	$data = digest_get($key);
	if (!isset($data) || !isset($data['vhash'])) {
		return disp_email_verification_failed();
	}
	$form = $config['form'];
	init_form($form);
	$field = $form['hash']['/admin/'];
	if (!isset($field['config_file'])) {
		return disp_email_verification_failed();
	}
	install_write_config($field['config_file'], $field['config_file'], $data['vhash']);
	disp_email_verification_success($data);
	return;
} // end of function handle_email

function install_get_base_path ()
{
	return url_dirname(request_get_base_path(), 2);
} // end of function install_get_base_path
function install_get_base_url ()
{
	return url_dirname(request_get_base_url());
} // end of function install_get_base_url
function install_navigate ($url, &$out=NULL)
{
	$us = parse_url($url);
	if (!isset($us['scheme']) || !$us['scheme']) {
		$url = install_get_base_url() . $url;
	}
	return navigate($url, $out);
} // end of function install_navigate

function install_write_config ($from, $to, $env)
{
	$status = 0;
	do {
		if (($source = file_get_contents($from)) === false) { $status = "Не могу открыть шаблон конфигурационного файла \"$from\""; break; }
		foreach ($env as $k=>$v) {
			// match (/*param_name[*/)(value)(/*]*/)
			$search[] = '#('.preg_quote('/*'.$k.'[*/', '#').')(.*)('.preg_quote('/*]*/', '#').')#';
			$replace[] = '\1'.phplang_write_string($v).'\3';
		}
		$source = preg_replace($search, $replace, $source);
		if (file_put_contents($to, $source) === false) { $status = "Не могу записать конфигурацонный файл \"$to\""; break; }
	} while (false);
	return $status;
} // end of function install_write_config

function email_quote_address($what)
{
	return '<'.$what.'>';
}

function digest_key()
{
	return md5(uniqid().time());
}
function digest_get($key)
{
	return digest_store($key, NULL, NULL, 0);
}
function digest_put($key, $data, $expire=NULL)
{
	return digest_store($key, $data, $expire, 1);
}
function digest_store_write(&$data)
{
	global $config;
	$file = $config['digest_store'];
	$script = '<'.'?php return '.var_export($data, true).';?>';
	return file_put_contents($file, $script);
}
function digest_store($key, $data, $expire, $action)
{
	static $store;
	if (!isset($store)) {
		global $config;
		$file = $config['digest_store'];
		if (file_exists($file)) {
			$store = include $file;
		} else {
			$store = array();
		}
	}

	if ($action === 0) {
		// get
		if (isset($store[$key])) {
			if (isset($store['_expire'][$key]) && $store['_expire'][$key] < time()) {
				// key value is expired
				unset($store[$key], $store['_expire'][$key]);
				digest_store_write($store);
				return NULL;
			} else {
				return $store[$key];
			}
		} else {
			return NULL;
		}
	} else {
		// put
		$store[$key] = $data;
		if (isset($expire) && $expire < time() - 100) {
			$expire += time();
		}
		$store['_expire'][$key] = $expire;
		return digest_store_write($store) ? $key : NULL;
	}
}

function install_identify($config_file, $ask)
{
	require ($config_file);
	
	return $ask['login'] === $self['admin_email']
		&& md5($ask['password'].$self['project_key']) === $self['admin_password'];
}

function install_validate_not_empty (&$f)
{
	if (!$f->value) return 'Поле обязательно для заполнения';
} // end of function install_validate_not_empty
function install_validate_db ($f)
{
	$xs = $f->_form->vhash;
	$db = @mysql_connect($xs['db_host'], $xs['db_user'], $xs['db_password']);
	if (!$db) {
		return sprintf('Не могу подключиться к серверу MySQL. Сообщение сервера: "%s".', mysql_error());
	}
	$rs = @mysql_select_db($xs['db_name'], $db);
	if (mysql_error($db)) {
		return sprintf('Не могу выбрать базу данных. Сообщение сервера: "%s".', mysql_error($db));
	}

	// MySQL version check
	$mysql_min_version = '5.0.0';
	$str = mysql_get_server_info($db);
	if (!preg_match('#([[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+)#', $str, $ms)) {
		return sprintf('Не могу определить версию сервера MySQL. Версия вашего SQL сервера "%s".', $str);
	}
	if (version_compare($mysql_min_version, $ms[1]) > 0) {
		return sprintf('Версия сервера MySQL должна быть не ниже "%s", а сейчас "%s".', $mysql_min_version, $ms[1]);
	}

	// InnoDB check at MySQL server
	if (!($rs = mysql_query("SHOW VARIABLES LIKE 'have_innodb'", $db))) {
		return sprintf('Не могу получить доступ к переменным сервера MySQL');
	}
	$mvars = array();
	while ($row = mysql_fetch_array($rs)) {
		list($name, $value) = $row;
		$mvars[$name] = $value;
	}
	if (!isset($mvars['have_innodb']) || $mvars['have_innodb'] !== 'YES') {
		return sprintf('Сервер MySQL не поддерживает InnoDB');
	}

} // end of function install_validate_db
function install_validate_auth ($f)
{
	if (!install_identify($f->config_file, $f->_form->vhash)) {
		return sprintf('Ошибка аунтентификации');
	}
} // end of function install_validate_db
function install_validate_admin_email($field)
{
	global $config;
	require_once $config['dir.install'].'lib/htmlMimeMail5/htmlMimeMail5.php';

	$name = $field->name;
	$field->validator_link = request_get_base_url() . '?m=admin_email&act=confirm&d='.
		digest_put(
			digest_key(),
			array(
				'vhash' => array($name => $field->value),
				'path' => array($name => $field->_path)
			),
			60*60*24*2
		);
	$from    = email_quote_address($field->value);
	$to      = array(email_quote_address($field->old_value));
	$subject = trim(call_disp('disp_validate_admin_email_subject', $field));
	$text    = call_disp('disp_validate_admin_email_text', $field);
	$html    = trim(call_disp('disp_validate_admin_email_html', $field));

	$mail = new HtmlMimeMail5();
	$mail->setFrom($from);
	$mail->setReturnPath($from);
	$mail->setSubject($subject);
	$mail->setHTMLEncoding(new QPrintEncoding());
	$mail->setTextEncoding(new QPrintEncoding());
	$mail->setTextWrap(60);
	$mail->setHTMLCharset('UTF-8');
	$mail->setTextCharset('UTF-8');
	$mail->setHeadCharset('UTF-8');

	if ($text) $mail->setText($text);
	if ($html) $mail->setHtml($html);

	$status = $mail->send($to, 'mail');

	if ($status) {
		return sprintf('На ваш почтовый адрес выслано письмо. Ждем подтверждения.');
	} else {
		return sprintf('Ошибка отправки уведомления. Смена email не возможна.');
	}
}

function install_config_db(&$field)
{
	require ($field['config_file']);
	foreach ($field['fields'] as $fn=>&$fc) {
		if (isset($config[$fn])) {
			$fc['value'] = $config[$fn];
		}
	}
}

function call_disp()
{
	$args = func_get_args();
	$f = $args[0]; unset($args[0]);
	ob_start();
	$r = call_user_func_array($f, $args);
	if (!isset($r)) $r = ob_get_clean();
	else ob_end_clean();
	return $r;
}
function php_is_writable ($path)
{
	if (is_dir($path))
		return php_is_writable(rtrim($path, '\\/') .'/'.uniqid(time().rand()).'.tmp');
	// tmp file for read/write capabilities
	$rm = file_exists($path);
	$f = @fopen($path, 'a');
	if ($f===false)
		return false;
	fclose($f);
	if (!$rm)
		unlink($path);
	return true;
} // end of function php_is_writable

function phplang_write_string($what)
{
	$res = '"'.
			str_replace( "\\", "\\\\",
			str_replace( "\"", "\\\"",
			str_replace( "\$", "\\\$",
			str_replace( "\n", "\\n",
			str_replace( "\r", "",
			$what ))))).'"';
	return $res;
}

function navigate ($url, &$out=NULL)
{
	$ch = curl_init($url);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	$out = curl_exec($ch);
	$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
	curl_close($ch);
	return $http_code;
} // end of function navigate




global $CONFIG;
if (!isset($CONFIG)) $CONFIG='';
function config_write_code ($code)
{
	global $CONFIG;
	$CONFIG .= $code ."\n";
} // end of function config_write_op
function config_write_param ($name, $value)
{
	config_write_code("\$config['$name'] = $value;\n");
} // end of function config_write_op
function config_write_param_string ($name, $value)
{
	$value = str_replace('\\', '\\\\', $value);
	$value = str_replace("'", "\'", $value);
	config_write_code("\$config['$name'] = '$value';\n");
} // end of function config_write_op


function disp_success($msg)
{
	if (request_get_param('debug')) {
		echo "<div>$msg [Ok]</div>";
	}
	return true;
}
function disp_fail($msg)
{
	echo "<div class=\"error\">$msg [Failed]</div>";
	return false;
}
function disp_check_writable ($path)
{
	return disp_assert(php_is_writable($path), "Is writable \"$path\"");
} // end of function disp_check_writable
function disp_assert ($bool, $message, $fail_message=NULL)
{
	if ($bool) disp_success($message);
	else disp_fail(isset($fail_message) ? $fail_message : $message);
	return $bool;
} // end of function disp_assert

function tpl_engine()
{
	static $tpl;
	if (!isset($tpl)) {
		global $config;
		$c = array();
		$c[        'tpl_base_dir']   = $config['dir.install'];
		$c[       'tpl_base_path']   = url_dirname(request_get_base_path(),2);
		$c[       'tpl_cache_dir']   = $config['dir.install'].'var/cache/';
		$c[       'tpl_data_dir']    = $config['dir.install'].'data/';
		$c[            'tpl_dirs'][] = $config['dir.install'].'lib/tpl/';
		$c[            'tpl_dirs'][] = $config['dir.install'].'skins/platonica/';
		$c[            'tpl_dirs'][] = $config['dir.install'].'admin/';
		//$c[       'tpl_compile']   = TPL_COMPILE_NEVER;
		//$c[          'tpl_prefix']   = '{';
		//$c[         'tpl_postfix']   = '}';
		//$c[    'tpl_construct_if']   = 'if';
		//$c['tpl_construct_ifelse']   = 'else(?:if)?';

		$p = array(
			array(
				'compiler_plugins', array(
					array('output_filter', 'compiler_filter_packer'),
				),
			),
		);

		require_once $config['dir.install'].'lib/includes/debug.php';
		require_once $config['dir.install'].'lib/tpl/Tpl.php';
		$tpl = new Tpl($c);
		$tpl->register_plugins($p);
		// путь к корню админки
		$tpl->set('/',    request_get_base_path());
		$tpl->set('base_path',    url_dirname(request_get_base_path(),2));
		// путь к корню инсталляции
	}
	return $tpl;
}

function disp_form ($f)
{
	$tpl = tpl_engine();

	$tpl->set('form', $f);
	echo $tpl->parse('form.html', 'body');
} // end of function disp_form

function disp_installation_success()
{
	$project_base_url = install_get_base_url();
?>
	<h1>Установка завершена</h1>
	<p>Мои поздравления. У Вас получилось! <a href="<?=$project_base_url?>"><?=$project_base_url?></a></p>
	<p class="dry-">С уважением, Инсталятор Платоники.</p>
	<div class="warning">
		<p>В целях безопасности, настоятельно рекомендуем удалить с сервера директорию инсталятора&nbsp;Платоники <br /><br /><strong><?=url_dirname(__FILE__)?></strong></p>
	</div>
	<a href="<?=$project_base_url?>"><img src="../skins/platonica/images/title/button-installend.gif" alt="Завершить установку" /></a>

<?php
}
function disp_installation_failed()
{
?>
		<h1>Установка невозможна</h1>
		<p>Я очень старался, но что-то пошло не так как ожидалось. Теперь вся надежда на Вас.</p>
		<p>Устраните неполадки и запустите инсталятор Платоники еще раз.</p>
		<p class="dry-">С уважением, Инсталятор Платоники.</p>
		<br /><br />
		<h1>Произошедшие ошибки</h1>
<?php
}

function disp_validate_admin_email_subject($field)
{
?>
Вы просили сменить email админа?
<?php
}
function disp_validate_admin_email_text($field)
{
?><?php
}
function disp_validate_admin_email_html(&$field)
{
?>
<h1>
Вы просили сменить email админа на <?=$field->value?>?
</h1>

<p>Можете проигнорировать</p>

<p>
Для подтверждения кликните на ссылке
	<a href="<?=$field->validator_link?>"><?=$field->validator_link?></a>
</p>
<?php
}
function disp_email_verification_failed($field)
{
?>
<h1>
Смена Email адреса
</h1>

<p>Извините, действие не может быть выполенно.</p>

<p>
	<a href="<?=request_get_base_path()?>">Начало</a>
</p>
<?php
}
function disp_email_verification_success($field)
{
?>
<h1>
Смена Email адреса
</h1>

<p>
Адрес электронной почты изменен.
	<a href="<?=request_get_base_path()?>">Начало</a>
</p>
<?php
}

global $RH_ATF, $RH_STATE, $RH_EVENT;
$RH_ATF[$RH_STATE][$RH_EVENT] = 'handle';
return handle();
